﻿using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Minestorm.Screens;
using Minestorm.Evolved.IoC;
using Minestorm.Evolved.Assets;
using Minestorm.Evolved.Scenes;

namespace Minestorm.Evolved.Screens
{
    public class DeviceState
    {
        public int BackBufferWidth { get; set; }
        public int BackBufferHeight { get; set; }
        public bool PreferMultiSampling { get; set; }
    }

    public class GameplayScreen : GameScreen
    {
        private IObjectFactory _iocContainer;
        private DeviceState _deviceState;
        private GraphicsDevice _graphics;
        private Scene _scene;
 
        public GameplayScreen()
        {
            _deviceState = null;
            _iocContainer = null;
        }

        private void SaveBackBufferInformation(GraphicsDeviceManager device)
        {
            _deviceState = new DeviceState()
            {
                BackBufferWidth = device.PreferredBackBufferWidth,
                BackBufferHeight = device.PreferredBackBufferHeight,
                PreferMultiSampling = device.PreferMultiSampling
            };
        }

        public override void LoadContent()
        {
            _iocContainer = new ObjectFactory();
            _iocContainer.RegisterSingleton<IContentManager, AssetContentManager>(new AssetContentManager(ScreenManager.Game.Services));
            _iocContainer.RegisterSingleton<IAssetManager, AssetManager>(new AssetManager(_iocContainer));

            var device = ScreenManager.DeviceManager;

            SaveBackBufferInformation(device);

            device.PreferredBackBufferWidth = 1280;
            device.PreferredBackBufferHeight = 720;
            device.PreferMultiSampling = true;
            device.ApplyChanges();

            _scene = new MapScene(_iocContainer, ScreenManager.GraphicsDevice);

            _scene.LoadContent();

            _graphics = ScreenManager.GraphicsDevice;
        }

        public override void UnloadContent()
        {
            _scene.UnloadContent();

            _iocContainer.InstanceOf<IContentManager>().Unload();

            _iocContainer.Dispose();

            var device = ScreenManager.DeviceManager;

            device.PreferredBackBufferWidth = _deviceState.BackBufferWidth;
            device.PreferredBackBufferHeight = _deviceState.BackBufferHeight;
            device.PreferMultiSampling = _deviceState.PreferMultiSampling;

            try
            {
                device.ApplyChanges();
            }
            catch (ObjectDisposedException)
            {
                //Do nothing, game is exiting
            }
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            _scene.Update(gameTime);
        }

        public override void HandleInput(InputState input)
        {
            _scene.HandleInput(input);
        }

        public override void Draw(GameTime gameTime)
        {
            _graphics.Clear(Color.Black);

            _scene.Draw(gameTime);
        }
    }
}
